/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : app_freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usbd_cdc_if.h"
#include "usb_device.h"
#include "fdcan.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
osSemaphoreId sem_cdc_rx;
osSemaphoreId sem_cdc_tx;
osSemaphoreId sem_can_rx;
osSemaphoreId sem_can_tx;
extern USBD_HandleTypeDef hUsbDeviceFS;

/* USER CODE END Variables */
/* Definitions for cdc_rx */
osThreadId_t cdc_rxHandle;
const osThreadAttr_t cdc_rx_attributes = {
  .name = "cdc_rx",
  .priority = (osPriority_t) osPriorityLow,
  .stack_size = 128 * 4
};
/* Definitions for cdc_tx */
osThreadId_t cdc_txHandle;
const osThreadAttr_t cdc_tx_attributes = {
  .name = "cdc_tx",
  .priority = (osPriority_t) osPriorityLow,
  .stack_size = 128 * 4
};
/* Definitions for can_rx */
osThreadId_t can_rxHandle;
const osThreadAttr_t can_rx_attributes = {
  .name = "can_rx",
  .priority = (osPriority_t) osPriorityLow,
  .stack_size = 128 * 4
};
/* Definitions for can_tx */
osThreadId_t can_txHandle;
const osThreadAttr_t can_tx_attributes = {
  .name = "can_tx",
  .priority = (osPriority_t) osPriorityLow,
  .stack_size = 128 * 4
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */

_Noreturn void cdc_rx_task(void *argument);

_Noreturn void cdc_tx_task(void *argument);

_Noreturn void can_rx_task(void *argument);

_Noreturn void can_tx_task(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  osSemaphoreDef(sem_cdc_rx);
  sem_cdc_rx = osSemaphoreNew(NUM_RX_BUFS, 0, osSemaphore(sem_cdc_rx));
  osSemaphoreDef(sem_cdc_tx);
  sem_cdc_tx = osSemaphoreNew(1, 0, osSemaphore(sem_cdc_tx));
  osSemaphoreDef(sem_can_rx);
  sem_can_rx = osSemaphoreNew(1, 0, osSemaphore(sem_can_rx));
  osSemaphoreDef(sem_can_tx);
  sem_can_tx = osSemaphoreNew(1, 0, osSemaphore(sem_can_tx));
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of defaultTask */

  /* creation of cdc_rx */
  cdc_rxHandle = osThreadNew(cdc_rx_task, NULL, &cdc_rx_attributes);

  /* creation of cdc_tx */
  cdc_txHandle = osThreadNew(cdc_tx_task, NULL, &cdc_tx_attributes);

  /* creation of can_rx */
  can_rxHandle = osThreadNew(can_rx_task, NULL, &can_rx_attributes);

  /* creation of can_tx */
  can_txHandle = osThreadNew(can_tx_task, NULL, &can_tx_attributes);

  /* USER CODE BEGIN RTOS_THREADS */

  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_cdc_rx_task */
/**
* @brief Function implementing the cdc_rx thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_cdc_rx_task */
_Noreturn void cdc_rx_task(void *argument)
{
  /* USER CODE BEGIN cdc_rx_task */
  /* Infinite loop */
    for(;;){
        if (osSemaphoreAcquire(sem_cdc_rx, osWaitForever) == osOK){
            cdc_process();
        }
    }
  /* USER CODE END cdc_rx_task */
}

/* USER CODE BEGIN Header_cdc_tx_task */
/**
* @brief Function implementing the cdc_tx thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_cdc_tx_task */
_Noreturn void cdc_tx_task(void *argument)
{
  /* USER CODE BEGIN cdc_tx_task */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
    osSemaphoreAcquire(sem_cdc_tx, osWaitForever);
  }
  /* USER CODE END cdc_tx_task */
}

/* USER CODE BEGIN Header_can_rx_task */
/**
* @brief Function implementing the can_rx thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_can_rx_task */
_Noreturn void can_rx_task(void *argument)
{
  /* USER CODE BEGIN can_rx_task */
  /* Infinite loop */
  for(;;){
    osDelay(1);
    if (osSemaphoreAcquire(sem_can_rx, osWaitForever) == osOK){
        can_process();
    }
  }
  /* USER CODE END can_rx_task */
}

/* USER CODE BEGIN Header_can_tx_task */
/**
* @brief Function implementing the can_tx thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_can_tx_task */
_Noreturn void can_tx_task(void *argument)
{
  /* USER CODE BEGIN can_tx_task */
  /* Infinite loop */
  for(;;){
    osDelay(1);
    osStatus sem_stat = osSemaphoreAcquire(sem_can_tx, osWaitForever);
  }
  /* USER CODE END can_tx_task */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */

